package v1

import (
	"fmt"
	"log"
	"net/http"
	"strconv"
	"strings"

	"github.com/gin-gonic/gin"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
	"syuee.com/iShot/common"
	"syuee.com/iShot/dto"
	"syuee.com/iShot/model"
	"syuee.com/iShot/response"
)

type UserController struct {
}

/**
* 获取所有管理员
* @param  {[type]}   conditions 查询条件
* 查询条件统一规范
* conditions
       {
               "query" : 关键词查询,
               "pagenum" : 页数,
               "pagesize" : 每页长度
       }
*
*/

func (con UserController) GetAllManagers(ctx *gin.Context) {

	manager := []model.I_manager{}
	queryparame := dto.Query_Dto{}
	DB := common.GetDB()
	var totalpage int64
	// query := ctx.PostForm("query")
	// pagenum, _ := strconv.Atoi(ctx.PostForm("pagenum"))
	// pagesize, _ := strconv.Atoi(ctx.PostForm("pagesize"))
	query := ctx.Request.FormValue("query")
	pagenum, _ := strconv.Atoi(ctx.Request.FormValue("pagenum"))
	pagesize, _ := strconv.Atoi(ctx.Request.FormValue("pagesize"))

	// if strings.Contains(ctx.GetHeader("Content-Type"), "application/json") {
	// 	ctx.BindJSON(&queryparame)
	// 	fmt.Printf("%#v\n", queryparame)
	// } else {
	queryparame.Query = query
	queryparame.Pagenum = pagenum
	queryparame.Pagesize = pagesize
	//}

	//fmt.Printf("%#v\n", queryparame)
	start := (queryparame.Pagenum - 1) * queryparame.Pagesize
	if queryparame.Pagenum == 0 {
		response.Response(ctx, http.StatusUnprocessableEntity, nil, 422, "传入pagenum参数错误")
		return
	}
	if queryparame.Pagesize == 0 {
		response.Response(ctx, http.StatusUnprocessableEntity, nil, 422, "传入Pagesize参数错误")
		return
	}
	queryname := fmt.Sprintf("%%%s%%", queryparame.Query)

	err := DB.Where("mg_name like ?", queryname).Offset(start).Limit(queryparame.Pagesize).Order("mg_id desc").Find(&manager).Offset(-1).Limit(-1).Count(&totalpage).Error
	if err != nil {
		response.Response(ctx, http.StatusInternalServerError, nil, 422, "查询失败")

	} else {
		response.Success(ctx, gin.H{"total": totalpage, "pagenum": queryparame.Pagenum, "users": dto.UserDto{}.ToUserDtoAll(manager)}, "success")

	}
}

/**
 * 创建管理员-
 *
 * @param  {[type]}   user 用户数据集
 */

func (con UserController) CreateManager(ctx *gin.Context) {
	manager := model.I_manager{}
	DB := common.GetDB()

	//从请求中获取参数
	ctx.Bind(&manager)
	username := manager.Mg_name
	password := manager.Mg_pwd
	//数据验证
	if len(username) == 0 {
		response.Response(ctx, http.StatusUnprocessableEntity, nil, 422, "必须输入用户名")
		return
	}
	if len(password) == 0 {
		response.Response(ctx, http.StatusUnprocessableEntity, nil, 422, "必须输入密码")
		return
	}
	//判断用户是否存在
	if isUserNameExist(DB, username, &manager) {
		response.Response(ctx, http.StatusUnprocessableEntity, nil, 422, "用户存在")
		return
	}
	//创建用户
	hasedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
	if err != nil {
		response.Response(ctx, http.StatusInternalServerError, nil, 500, "加密错误")
		return
	}
	manager.Mg_pwd = string(hasedPassword)

	//返回响应
	if err = DB.Create(&manager).Error; err != nil {
		response.Response(ctx, http.StatusInternalServerError, nil, 500, "创建失败")
	} else {
		//返回结果
		response.SuccessUser(ctx, dto.UserDto{}.ToUserDto(manager), "创建成功")
	}

}

/**
 * 更新管理员状态
 *
 * @param  {[type]}   params 管理员信息
 */
func (con UserController) UpdateManagerState(ctx *gin.Context) {
	manager := model.I_manager{}
	DB := common.GetDB()

	id, ok := ctx.Params.Get("uid")
	if !ok {
		response.Response(ctx, http.StatusInternalServerError, nil, 422, "无效id1")
		return
	}
	utype, okt := ctx.Params.Get("type")
	if !okt {
		response.Response(ctx, http.StatusInternalServerError, nil, 422, "type不存在")
		return
	}

	if err := DB.Where("mg_id=?", id).First(&manager).Error; err != nil {
		response.Response(ctx, http.StatusInternalServerError, nil, 422, "无效id1")
		return
	}
	if utype == "true" || utype == "false" {
		b, _ := strconv.ParseBool(utype)
		i := 0
		if b {
			i = 1
		}
		manager.Mg_state = i
		if err := DB.Save(&manager).Error; err != nil {
			response.Response(ctx, http.StatusInternalServerError, nil, 422, "更改失败")

		} else {
			response.SuccessUser(ctx, dto.UserDto{}.ToUserDto(manager), "修改成功")

		}

	} else {
		response.Response(ctx, http.StatusInternalServerError, nil, 422, "type传递无效")

	}

}

/**
 * 通过管理员 ID 获取管理员信息
 *
 * @param  {[type]}   id 管理员 ID
 */

func (con UserController) GetManager(ctx *gin.Context) {
	manager := model.I_manager{}
	DB := common.GetDB()

	id, ok := ctx.Params.Get("id")
	if !ok {
		response.Response(ctx, http.StatusInternalServerError, nil, 422, "无效id1")
		return
	}

	if err := DB.Where("mg_id=?", id).First(&manager).Error; err != nil {
		response.Response(ctx, http.StatusInternalServerError, nil, 422, "无效id1")
		return
	}
	response.SuccessUser(ctx, dto.UserDto{}.ToUserDto(manager), "获取成功")

}

/**
 * 更新管理员信息
 *
 * @param  {[type]}   params 管理员信息
 */
func (con UserController) UpdateManager(ctx *gin.Context) {
	manager := model.I_manager{}
	DB := common.GetDB()

	id, ok := ctx.Params.Get("uid")
	if !ok {
		response.Response(ctx, http.StatusInternalServerError, nil, 422, "无效id")
		return
	}

	//从请求中获取参数
	ctx.Bind(&manager)

	//更新用户
	user := model.I_manager{}
	if err := DB.Where("mg_id=?", id).Find(&user).Error; err != nil {
		response.Response(ctx, http.StatusInternalServerError, nil, 422, "更改失败")
	}
	user.Mg_email = manager.Mg_email
	user.Mg_mobile = manager.Mg_mobile
	if err := DB.Save(&user).Error; err != nil {
		response.Response(ctx, http.StatusInternalServerError, nil, 422, "更改失败")

	} else {
		response.SuccessUser(ctx, dto.UserDto{}.ToUserDto(manager), "修改成功")

	}

}

/**
 * 通过管理员 ID 进行删除操作
 *
 * @param  {[type]}   id 管理员ID
 */

func (con UserController) DeleteManager(ctx *gin.Context) {
	manager := model.I_manager{}
	DB := common.GetDB()

	id, ok := ctx.Params.Get("id")
	if !ok {
		response.Response(ctx, http.StatusInternalServerError, nil, 422, "无效id")
		return
	}

	if err := DB.Where("mg_id=?", id).Delete(&manager).Error; err != nil {
		response.Response(ctx, http.StatusInternalServerError, nil, 422, "无效id")
		return
	}
	response.Success(ctx, nil, "删除成功")

}

/**
 * 为管理员设置角色
 *
 * @param {[type]}   id  管理员ID
 * @param {[type]}   rid 角色ID
 */

func (con UserController) SetRole(ctx *gin.Context) {

}

/**
 * 管理员登录
 * @param  {[type]}   username 用户名
 * @param  {[type]}   password 密码
 */

func (con UserController) Login(ctx *gin.Context) {
	manager := model.I_manager{}
	DB := common.GetDB()

	username := ctx.PostForm("username")
	password := ctx.PostForm("password")

	//获取参数
	if strings.Contains(ctx.GetHeader("Content-Type"), "application/json") {
		ctx.BindJSON(&manager)
		fmt.Printf("%#v\n", manager)
	} else {
		manager.Mg_name = username
		manager.Mg_pwd = password
	}

	//数据验证
	if len(manager.Mg_name) == 0 {
		response.Response(ctx, http.StatusUnprocessableEntity, nil, 422, "必须输入用户名")
		return
	}
	if len(manager.Mg_pwd) == 0 {
		response.Response(ctx, http.StatusUnprocessableEntity, nil, 422, "必须输入密码")
		return
	}
	var user model.I_manager
	//判断用户是否存在
	if !isUserNameExist(DB, manager.Mg_name, &user) {
		response.Response(ctx, http.StatusUnprocessableEntity, nil, 422, "用户不存在")
		return
	}

	//判断密码是否正确
	if err := bcrypt.CompareHashAndPassword([]byte(user.Mg_pwd), []byte(manager.Mg_pwd)); err != nil {
		response.Response(ctx, http.StatusBadRequest, nil, 400, "密码错误")

		return

	}

	//发放token
	token, err := common.ReleaseToken(user)

	if err != nil {
		response.Response(ctx, http.StatusInternalServerError, nil, 500, "系统异常")
		log.Printf("token generate error: %v", err)
		return
	}

	//返回结果
	response.SuccessToken(ctx, dto.UserDtoToken{}.ToUserDto(user, token), "登录成功")

}

/**
 * 管理员注册
 * @param  {[type]}   username 用户名
 * @param  {[type]}   password 密码
 */
func (con UserController) Register(ctx *gin.Context) {
	manager := model.I_manager{}
	DB := common.GetDB()

	username := ctx.PostForm("username")
	password := ctx.PostForm("password")

	//获取参数
	if strings.Contains(ctx.GetHeader("Content-Type"), "application/json") {
		ctx.BindJSON(&manager)
		fmt.Printf("%#v\n", manager)
	} else {
		manager.Mg_name = username
		manager.Mg_pwd = password
	}

	//fmt.Println(username, password)

	//数据验证
	if len(manager.Mg_name) == 0 {
		response.Response(ctx, http.StatusUnprocessableEntity, nil, 422, "必须输入用户名")
		return
	}
	if len(manager.Mg_pwd) == 0 {
		response.Response(ctx, http.StatusUnprocessableEntity, nil, 422, "必须输入密码")
		return
	}
	//判断用户是否存在
	if isUserNameExist(DB, manager.Mg_name, &manager) {
		response.Response(ctx, http.StatusUnprocessableEntity, nil, 422, "用户存在")
		return
	}
	//创建用户
	hasedPassword, err := bcrypt.GenerateFromPassword([]byte(manager.Mg_pwd), bcrypt.DefaultCost)
	if err != nil {
		response.Response(ctx, http.StatusInternalServerError, nil, 500, "加密错误")
		return
	}
	newUser := model.I_manager{
		Mg_name: manager.Mg_name,
		Mg_pwd:  string(hasedPassword),
	}
	DB.Create(&newUser)

	//返回结果
	//发放token
	token, err := common.ReleaseToken(newUser)

	if err != nil {
		response.Response(ctx, http.StatusInternalServerError, nil, 500, "系统异常")
		log.Printf("token generate error: %v", err)
		return
	}
	//返回结果
	response.SuccessToken(ctx, dto.UserDtoToken{}.ToUserDto(newUser, token), "注册成功")

}

//判断用户名是否存在
func isUserNameExist(db *gorm.DB, username string, user *model.I_manager) bool {
	//var user model.I_manager
	db.Where("mg_name = ?", username).First(&user)
	return user.Mg_id != 0
}
